import sys
sys.path.insert(0,'..')

from rmpoly import *
from time import time
from gmpy import mpq

try:
  import psyco
  psyco.full()
except:
  pass


def ex_k3(order):
  # Katsura 3
  gens = ['x%d' % i for i in range(2,-1,-1)]
  rp = RPoly(gens,6,mpq,order=order)
  x2,x1,x0 = rp.gens()
  I = [x0 + 2*x1 + 2*x2 - 1, x0**2 + 2*x1**2 + 2*x2**2 - x0, 2*x0*x1 + 2*x1*x2 - x1]
  gr = groebner_basis(I)
  return gr


def ex_k4(order):
  # Katsura 4
  gens = ['x%d' % i for i in range(3,-1,-1)]
  rp = RPoly(gens,6,mpq,order=order)
  x3,x2,x1,x0 = rp.gens()
  I = [x0 + 2*x1 + 2*x2 + 2*x3 - 1, x0**2 + 2*x1**2 + 2*x2**2 + 2*x3**2 - x0, 2*x0*x1 + 2*x1*x2 + 2*x2*x3 - x1, x1**2 + 2*x0*x2 + 2*x1*x3 - x2]
  gr = groebner_basis(I)
  return gr


def ex_k5(order):
  # Katsura 5
  gens = ['x%d' % i for i in range(4,-1,-1)]
  rp = RPoly(gens,6,mpq,order=order)
  x4,x3,x2,x1,x0 = rp.gens()
  I = [x0 + 2*x1 + 2*x2 + 2*x3 + 2*x4 - 1, x0**2 + 2*x1**2 + 2*x2**2 + 2*x3**2 + 2*x4**2 - x0, 2*x0*x1 + 2*x1*x2 + 2*x2*x3 + 2*x3*x4 - x1, x1**2 + 2*x0*x2 + 2*x1*x3 + 2*x2*x4 - x2, 2*x1*x2 + 2*x0*x3 + 2*x1*x4 - x3]
  gr = groebner_basis(I)
  return gr

def ex_k6(order):
  # Katsura 6
  gens = ['x%d' % i for i in range(5,-1,-1)]
  rp = RPoly(gens,6,mpq,order=order)
  x5,x4,x3,x2,x1,x0 = rp.gens()
  I = [x0 + 2*x1 + 2*x2 + 2*x3 + 2*x4 + 2*x5 - 1, x0**2 + 2*x1**2 + 2*x2**2 + 2*x3**2 + 2*x4**2 + 2*x5**2 - x0, 2*x0*x1 + 2*x1*x2 + 2*x2*x3 + 2*x3*x4 + 2*x4*x5 - x1, x1**2 + 2*x0*x2 + 2*x1*x3 + 2*x2*x4 + 2*x3*x5 - x2, 2*x1*x2 + 2*x0*x3 + 2*x1*x4 + 2*x2*x5 - x3, x2**2 + 2*x1*x3 + 2*x0*x4 + 2*x1*x5 - x4]
  gr = groebner_basis(I)
  return gr


def ex_k7(order):
  # Katsura 7
  gens = ['x%d' % i for i in range(6,-1,-1)]
  rp = RPoly(gens,7,mpq,order=order)
  x6,x5,x4,x3,x2,x1,x0 = rp.gens()
  # Katsura 7
  I = [x0 + 2*x1 + 2*x2 + 2*x3 + 2*x4 + 2*x5 + 2*x6 - 1, x0**2 + 2*x1**2 + 2*x2**2 + 2*x3**2 + 2*x4**2 + 2*x5**2 + 2*x6**2 - x0, 2*x0*x1 + 2*x1*x2 + 2*x2*x3 + 2*x3*x4 + 2*x4*x5 + 2*x5*x6 - x1, x1**2 + 2*x0*x2 + 2*x1*x3 + 2*x2*x4 + 2*x3*x5 + 2*x4*x6 - x2, 2*x1*x2 + 2*x0*x3 + 2*x1*x4 + 2*x2*x5 + 2*x3*x6 - x3, x2**2 + 2*x1*x3 + 2*x0*x4 + 2*x1*x5 + 2*x2*x6 - x4, 2*x2*x3 + 2*x1*x4 + 2*x0*x5 + 2*x1*x6 - x5]
  gr = groebner_basis(I)
  return gr


def ex_k8(order):
  # Katsura 8
  gens = ['x%d' % i for i in range(7,-1,-1)]
  rp = RPoly(gens,7,mpq,order=order)
  x7,x6,x5,x4,x3,x2,x1,x0 = rp.gens()
  I = [x0 + 2*x1 + 2*x2 + 2*x3 + 2*x4 + 2*x5 + 2*x6 + 2*x7 - 1, x0**2 + 2*x1**2 + 2*x2**2 + 2*x3**2 + 2*x4**2 + 2*x5**2 + 2*x6**2 + 2*x7**2 - x0, 2*x0*x1 + 2*x1*x2 + 2*x2*x3 + 2*x3*x4 + 2*x4*x5 + 2*x5*x6 + 2*x6*x7 - x1, x1**2 + 2*x0*x2 + 2*x1*x3 + 2*x2*x4 + 2*x3*x5 + 2*x4*x6 + 2*x5*x7 - x2, 2*x1*x2 + 2*x0*x3 + 2*x1*x4 + 2*x2*x5 + 2*x3*x6 + 2*x4*x7 - x3, x2**2 + 2*x1*x3 + 2*x0*x4 + 2*x1*x5 + 2*x2*x6 + 2*x3*x7 - x4, 2*x2*x3 + 2*x1*x4 + 2*x0*x5 + 2*x1*x6 + 2*x2*x7 - x5, x3**2 + 2*x2*x4 + 2*x1*x5 + 2*x0*x6 + 2*x1*x7 - x6]
  gr = groebner_basis(I)
  return gr

def ex_k9(order):
  # Katsura 9
  gens = ['x%d' % i for i in range(8,-1,-1)]
  rp = RPoly(gens,7,mpq,order=order)
  x8,x7,x6,x5,x4,x3,x2,x1,x0 = rp.gens()
  I= [x0 + 2*x1 + 2*x2 + 2*x3 + 2*x4 + 2*x5 + 2*x6 + 2*x7 + 2*x8 - 1, x0**2 + 2*x1**2 + 2*x2**2 + 2*x3**2 + 2*x4**2 + 2*x5**2 + 2*x6**2 + 2*x7**2 + 2*x8**2 - x0, 2*x0*x1 + 2*x1*x2 + 2*x2*x3 + 2*x3*x4 + 2*x4*x5 + 2*x5*x6 + 2*x6*x7 + 2*x7*x8 - x1, 2*x0*x2 + x1**2 + 2*x1*x3 + 2*x2*x4 + 2*x3*x5 + 2*x4*x6 + 2*x5*x7 + 2*x6*x8 - x2, 2*x0*x3 + 2*x1*x2 + 2*x1*x4 + 2*x2*x5 + 2*x3*x6 + 2*x4*x7 + 2*x5*x8 - x3, 2*x0*x4 + 2*x1*x3 + 2*x1*x5 + x2**2 + 2*x2*x6 + 2*x3*x7 + 2*x4*x8 - x4, 2*x0*x5 + 2*x1*x4 + 2*x1*x6 + 2*x2*x3 + 2*x2*x7 + 2*x3*x8 - x5, 2*x0*x6 + 2*x1*x5 + 2*x1*x7 + 2*x2*x4 + 2*x2*x8 + x3**2 - x6, 2*x0*x7 + 2*x1*x6 + 2*x1*x8 + 2*x2*x5 + 2*x3*x4 - x7]
  gr = groebner_basis(I)
  return gr


def ex_cy3():
  # Cyclic-3
  gens = ['x%d' % i for i in range(2,-1,-1)]
  rp = RPoly(gens,6,mpq,order = 'grlex')
  x2,x1,x0 = rp.gens()
  I = [x0 + x1 + x2, x0*x1 + x0*x2 + x1*x2, x0*x1*x2 - 1]
  gr = groebner_basis(I)
  return gr

def ex_cy4():
  # Cyclic-4
  gens = ['x%d' % i for i in range(3,-1,-1)]
  rp = RPoly(gens,6,mpq,order = 'grlex')
  x3,x2,x1,x0 = rp.gens()
  I = [x0 + x1 + x2 + x3, x0*x1 + x0*x3 + x1*x2 + x2*x3, x0*x1*x2 + x0*x1*x3 + x0*x2*x3 + x1*x2*x3, x0*x1*x2*x3 - 1]
  gr = groebner_basis(I)
  return gr


def ex_cy5():
  # Cyclic-5
  gens = ['x%d' % i for i in range(4,-1,-1)]
  rp = RPoly(gens,6,mpq,order = 'grlex')
  x4,x3,x2,x1,x0 = rp.gens()
  I = [x0 + x1 + x2 + x3 + x4, x0*x1 + x0*x4 + x1*x2 + x2*x3 + x3*x4, x0*x1*x2 + x0*x1*x4 + x0*x3*x4 + x1*x2*x3 + x2*x3*x4, x0*x1*x2*x3 + x0*x1*x2*x4 + x0*x1*x3*x4 + x0*x2*x3*x4 + x1*x2*x3*x4, x0*x1*x2*x3*x4 - 1]
  gr = groebner_basis(I)
  return gr


def ex_cy6():
  # Cyclic-6
  gens = ['x%d' % i for i in range(5,-1,-1)]
  rp = RPoly(gens,6,mpq,order = 'grlex')
  x5,x4,x3,x2,x1,x0 = rp.gens()
  I = [x0 + x1 + x2 + x3 + x4 + x5, x0*x1 + x0*x5 + x1*x2 + x2*x3 + x3*x4 + x4*x5, x0*x1*x2 + x0*x1*x5 + x0*x4*x5 + x1*x2*x3 + x2*x3*x4 + x3*x4*x5, x0*x1*x2*x3 + x0*x1*x2*x5 + x0*x1*x4*x5 + x0*x3*x4*x5 + x1*x2*x3*x4 + x2*x3*x4*x5, x0*x1*x2*x3*x4 + x0*x1*x2*x3*x5 + x0*x1*x2*x4*x5 + x0*x1*x3*x4*x5 + x0*x2*x3*x4*x5 + x1*x2*x3*x4*x5, x0*x1*x2*x3*x4*x5 - 1]
  gr = groebner_basis(I)
  return gr


def ex_mora(n):
  gens = ['x%d' % i for i in range(3,-1,-1)]
  exp_bits = 14
  assert(n**2 + 1 < 2**exp_bits)
  rp = RPoly(gens,exp_bits,mpq,order = 'grlex')
  x3,x2,x1,x0 = rp.gens()
  I = [x0**(n+1) - x1*x2**(n-1)*x3, x0*x1**(n-1) - x2**n, x0**n*x2-x1**n*x3]
  gr = groebner_basis(I)
  return gr

def run_katsura(N1,N2):
  " run katsura-n in range(N1,N2) "
  a =  [None,None,None,(ex_k3,'out/k3'),(ex_k4,'out/k4'),(ex_k5,'out/k5'),(ex_k6,'out/k6'),(ex_k7,'out/k7'),(ex_k8,'out/k8'),(ex_k9,'out/k9')][N1:N2]
  for f,fn in a:
    if not f:
      continue
    n = int(fn[-1])
    order = 'grlex'
    #order = tuple([1]*n)
    print 'k%d order=%s' % (n,order),
    t0 = time()
    p = f(order)
    t1 = time()
    print '%.2f' %(t1-t0)
    f = open(fn, 'w')
    f.write('%s' % p)
    f.close()
  
def run_cyclic(N1,N2):
  " run cyclic-n in range(N1,N2) "
  a = [None,None,None,(ex_cy3,'out/cy3'),(ex_cy4,'out/cy4'),(ex_cy5,'out/cy5'),(ex_cy6,'out/cy6')][N1:N2]
  for f,fn in a:
    if not f:
      continue
    n = int(fn[-1])
    print 'cy%d' % n,
    t0 = time()
    p = f()
    t1 = time()
    print '%.2f' %(t1-t0)
    f = open(fn, 'w')
    f.write('%s' % p)
    f.close()


def run_mora(N):
  " run mora-n in range(N1,N2) "
  for n in range(3,N,10):
    print 'ex_mora(%d)' % n
    fn = 'out/m%d' % n
    t0 = time()
    p = ex_mora(n)
    t1 = time()
    print '%.2f' %(t1-t0)
    f = open(fn, 'w')
    f.write('%s' % p)
    f.close()
         

"""
ex_k3('grlex')
ex_k4('grlex')
ex_k5('grlex')
ex_k6('grlex')
ex_k7('grlex')
run_katsura(3,7)
run_cyclic(3,6)

t0 = time()
t1 = time()
print '%.2f' %(t1-t0)
"""
run_mora(50)

